﻿/*************************************************************************
文件名称 ：ServiceBase.cs                          
描述说明 ：定义数据服务基类
**************************************************************************/

using System.Dynamic;
using Jw.Data;
using Jw.Utils;

namespace Jw.Core
{
    public class ServiceBase : ServiceBase<ModelBase>
    {
        public ServiceBase(string Module)
            : base(Module)
        {

        }
    }

    public partial class ServiceBase<T> where T : ModelBase, new()
    {
        public ServiceBase()
        {
            ModuleName = AttributeHelper.GetModuleAttribute(this.GetType());
            Msg = new AjaxMessge();
        }

        public ServiceBase(string moduleName)
        {
            ModuleName = moduleName;
            Msg = new AjaxMessge();
        }

        ~ServiceBase()
        {
            try
            {
                db.Dispose();
            }
            catch
            {
            }
        }

        public static ServiceBase<T> Instance()
        {
            return new ServiceBase<T>();
        }

        public int StoredProcedure(ParamSP param)
        {
            var result = 0;
            Logger("执存储过程", () => result = BuilderParse(param).Execute());
            return result;
        }

        public dynamic ScrollKeys(string key, string value, ParamQuery where = null)
        {
            dynamic result = new ExpandoObject();
            Logger("获取上一条下一条数据", () =>
            {
                result.current = value;
                var pFirst = ParamQuery.Instance().Select("top 1 " + key).OrderBy(key);
                var pPrevious = ParamQuery.Instance().Select("top 1 " + key).AndWhere(key, value, Cp.Less).OrderBy(key + " desc");
                var pNext = ParamQuery.Instance().Select("top 1 " + key).AndWhere(key, value, Cp.Greater).OrderBy(key);
                var pLast = ParamQuery.Instance().Select("top 1 " + key).OrderBy(key + " desc");

                if (where != null)
                {
                    foreach (var item in where.GetData().Where)
                    {
                        pFirst.AndWhere(item.Data.Column, item.Data.Value, item.Compare, item.Data.Extend);
                        pPrevious.AndWhere(item.Data.Column, item.Data.Value, item.Compare, item.Data.Extend);
                        pNext.AndWhere(item.Data.Column, item.Data.Value, item.Compare, item.Data.Extend);
                        pLast.AndWhere(item.Data.Column, item.Data.Value, item.Compare, item.Data.Extend);
                    }
                }

                result.first = GetField<string>(pFirst) ?? value;
                result.previous = GetField<string>(pPrevious) ?? value;
                result.next = GetField<string>(pNext) ?? value;
                result.last = GetField<string>(pLast) ?? value;

                result.previousEnable = !object.Equals(result.previous, result.current);
                result.nextEnable = !object.Equals(result.next, result.current);
                result.firstEnable = result.previousEnable && !object.Equals(result.first, result.current);
                result.lastEnable = result.nextEnable && !object.Equals(result.last, result.current);
            });
            return result;
        }

        /// <summary>
        /// 根据父亲编号得到最新继承父亲编号的子编号 格式如下 01  0101
        /// </summary>
        /// <param name="field"></param>
        /// <param name="pfield"></param>
        /// <param name="ParentCode"></param>
        /// <returns></returns>
        public string GetNewCode(string field, string pfield = "", string ParentCode = "", int length = 2)
        {
            int index = 0;
            string table = typeof(T).Name;
            string MaxCode = string.Empty;
            if (pfield == "")
            {
                //取表中的最大值加1
                MaxCode = db.Sql(string.Format("select isnull(max({0}),0) from {1}", field, table)).QuerySingle<string>();
                index = ZConvert.To<int>(MaxCode, 0);
                return (index + 1).ToString().PadLeft(length, '0');
            }
            else
            {
                //取表中的最大值 根据父编号进行设置
                MaxCode = db.Sql(string.Format("select isnull(max({0}),0) from {1} where {2}='{3}'", field, table, pfield, ParentCode)).QuerySingle<string>();
                if (MaxCode.Length < ParentCode.Length)
                {
                    index = ZConvert.To<int>(MaxCode, 0);
                }
                else
                {
                    index = ZConvert.To<int>(MaxCode.Substring(ParentCode.Length), 0);
                }
                return ParentCode + (index + 1).ToString().PadLeft(length, '0');
            }
        }


        public string GetNewKey(string field, string rule, int qty = 1, ParamQuery pQuery = null)
        {
            var result = string.Empty;

            Logger("获取新主键", () =>
            {
                for (var i = 0; i < qty; i++)
                {
                    string newkey, table = typeof(T).Name;
                    switch (rule)
                    {
                        case "guid":
                            newkey = NewKey.guid();
                            break;
                        case "datetime":
                            newkey = NewKey.datetime();
                            break;
                        case "dateplus":
                            newkey = NewKey.dateplus(db, table, field, "yyyyMMdd", 4);
                            break;
                        case "recordplus":
                            //行记录加 1
                            newkey = NewKey.recordplus(db, table, field, pQuery);
                            break;
                        case "maxplus":
                        default:
                            newkey = NewKey.maxplus(db, table, field, pQuery);
                            break;
                    }

                    result += "," + newkey;
                }
            });

            return result.Trim(',');
        }

        #region 变量
        private IDbContext _db;
        protected IDbContext db
        {
            get
            {
                if (_db == null)
                    _db = Db.Context(ModuleName);

                return _db;
            }
        }

        public AjaxMessge Msg { get; set; }
        public string ModuleName { get; set; }

        #endregion
    }
}
